﻿using System;
using System.Runtime.Serialization;
using System.Xml;
using SharpObjects.Configuration.ConfigurationProviders;
using SharpObjects.Instantiation;
using SharpObjects.Interfaces;

namespace SharpObjects.Configuration.Services
{
    [Serializable]
    [DataContract]
    public class ConfigurableTypeDescriptor : TypeDescriptor, IXmlInitializable
    {
        public ConfigurableTypeDescriptor()
            : base(null, null, null)
        {
            
        }

        public ConfigurableTypeDescriptor(string assemblyPath = null, string typeName = null, object[] arguments = null)
            : base(assemblyPath, typeName, arguments)
        {

        }


        #region IXmlInitializable Members

        public void Initialize(System.Xml.XmlElement initializationElement)
        {
            IConfigurationProvider init = new XmlConfigurationProvider(initializationElement);

            this.AssemblyPath = init.GetString("type_assembly_path", init.GetString("@type_assembly_path", null));
            this.TypeName = init.GetString("type_name", init.GetString("@type_name", null));

            if(this.AssemblyPath == null || this.TypeName == null)
            {
                throw new ArgumentException("Assembly path and type name must be specified in ConfigurableTypeDescriptor XML definition.");
            }

            XmlNodeList argumentNodes = initializationElement.SelectNodes("arguments/argument");

            if (argumentNodes.Count > 0)
            {
                this.Arguments = new object[argumentNodes.Count];
                for(int k = 0; k < argumentNodes.Count; k++)
                {
                    this.Arguments[k] = argumentNodes[k];
                }
            }

            this.IsInitialized = true;
        }

        public bool IsInitialized { get; set; }


        #endregion
    }
}
